package com.a0soft.gphone.aTruffleHog.wnd.stat;

import java.text.DateFormat;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.a0soft.gphone.aTruffleHog.R;
import com.a0soft.gphone.aTruffleHog.util.CONSTS;
import com.a0soft.gphone.aTruffleHog.util.aDebug;
import com.a0soft.gphone.aTruffleHog.widget.PieChartView;
import com.a0soft.gphone.aTruffleHog.widget.PieChartView.Adapter;
import com.a0soft.gphone.aTruffleHog.wnd.BaseDownloadFrg;

abstract class BaseStatFragment extends BaseDownloadFrg 
                                implements PieChartView.OnListener,
                                           AdapterView.OnItemClickListener {
    protected int           m_nType; //my device or all devices    
    protected String        m_strUserDefinedMID;
    
    protected long          m_lDataTime; //stat generated time
    protected int           m_nMyIdx; //m_stats index of my device 
    protected String        m_strMy;

    private TextView        m_tvLastUpdate;
    private PieChartView    m_vPieChart;
    private ListView        m_lvList;

    private int                             m_nLastCheckedPos; //active pie
    private ArrayList<? extends StatData>   m_stats;

    private static int TYPE_UNDEFINED = 0;
    
    private static final String EXTRA_PREFIX = BaseStatFragment.class.getName();
    private static final String EXTRA_CHECKED_POS = EXTRA_PREFIX + ".cp";    
    private static final String EXTRA_TYPE = EXTRA_PREFIX + ".type";  
    private static final String EXTRA_MID = EXTRA_PREFIX + ".mid";
    
    private static final String LOG_TAG = BaseStatFragment.class.getSimpleName();
    
    ////////////////////////////////////////
    public static final void 
    SetType(BaseStatFragment frg, int nType) 
    {
        Bundle args = new Bundle();
        args.putInt(EXTRA_TYPE, nType);
        frg.setArguments(args);
    }
    
    public static final void 
    SetTypeAndMID(BaseStatFragment frg, int nType, String strMID) 
    {
        Bundle args = new Bundle();
        args.putInt(EXTRA_TYPE, nType);
        args.putString(EXTRA_MID, strMID);
        frg.setArguments(args);
    }
    
    public
    BaseStatFragment()
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "BaseStatFragment()");
        //setHasOptionsMenu(true);
    }
    
    @Override public void 
    onCreate(Bundle bdSavedInstanceState)
    {
        super.onCreate(bdSavedInstanceState);
        
        //setHasOptionsMenu(true);
        
        _ReloadFromArguments(getArguments());
        
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onCreate(): m_nType=" + m_nType);
    }    
    
    private void 
    _ReloadFromArguments(Bundle bdArguments) 
    {
        m_nType = TYPE_UNDEFINED;
        if (bdArguments == null) {
            if (aDebug.ENABLED)
                aDebug.d(LOG_TAG, "_ReloadFromArguments(): bdArguments is null");
            return;
        }
        
        m_nType = bdArguments.getInt(EXTRA_TYPE, m_nType);
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "_ReloadFromArguments(): m_nType=" + m_nType);
        
        m_strUserDefinedMID = bdArguments.getString(EXTRA_MID);
    }
    
    @Override public View 
    onCreateView(LayoutInflater inflater, ViewGroup vgContainer,
                 Bundle bdSavedInstanceState)
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onCreateView(): m_nType=" + m_nType);
        View vRoot = inflater.inflate(R.layout.comm_stats_frg, vgContainer, false);
        
        //((TextView)vRoot.findViewById(R.id.title)).setText(R.string.os_stats_title);
        vRoot.findViewById(R.id.title).setVisibility(View.GONE);
        
        m_vTopPanel = vRoot.findViewById(R.id.top_panel);
        m_vWaitPanel = vRoot.findViewById(R.id.wait_panel);
        m_vEmptyResult = vRoot.findViewById(R.id.empty);
        m_tvError = (TextView)vRoot.findViewById(R.id.error);
        m_tvLastUpdate = (TextView)vRoot.findViewById(R.id.update_time);
        
        m_vPieChart = (PieChartView)vRoot.findViewById(R.id.chart);
        m_vPieChart.SetListener(this);        

        m_lvList = (ListView)vRoot.findViewById(R.id.list);        
        m_lvList.setOnItemClickListener(this);
        
        if (bdSavedInstanceState != null) {
            int nLastCheckedPos = bdSavedInstanceState.getInt(EXTRA_CHECKED_POS, -1);
            if (aDebug.ENABLED) {
                aDebug.d(LOG_TAG, "onRestoreInstanceState(): nLastCheckedPos=" + nLastCheckedPos);
            }
            m_nLastCheckedPos = nLastCheckedPos;
        }
        else {
            m_nLastCheckedPos = -1;
        } 
        
        m_nMyIdx = -1;
        
        return vRoot;
    }

    @Override public void 
    onAttach(Activity activity)
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onAttach(): m_nType=" + m_nType);
        super.onAttach(activity);
    }

    @Override public void 
    onDetach()
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onDetach(): m_nType=" + m_nType);
        super.onDetach();
    }

    @Override public void 
    onPause()
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onPause(): m_nType=" + m_nType);
        super.onPause();
    }

    @Override public void 
    onResume()
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onResume(): m_nType=" + m_nType);
        super.onResume();
    }

    @Override public void 
    onSaveInstanceState(Bundle outState)
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onSaveInstanceState(): m_nType=" + m_nType);
        super.onSaveInstanceState(outState);
        
        outState.putInt(EXTRA_CHECKED_POS, m_nLastCheckedPos);
    }
    
    /*@Override public void 
    onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onCreateOptionsMenu(): m_nType=" + m_nType);
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.comm_stats_frg, menu);
    }
    
    @Override public boolean 
    onOptionsItemSelected(MenuItem item)
    {
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onOptionsItemSelected(): m_nType=" + m_nType);
        final int ID = item.getItemId();
        if (ID == R.id.menu_refresh) {
            //this.getFragmentManager().findFragmentByTag(tag)
            return true;
        }
        return super.onOptionsItemSelected(item);
    }*/

    @Override protected boolean 
    IsMyDownloadCmd(int nCmd)
    {
        return false;
    }

    protected void
    SetStatData(ArrayList<? extends StatData> stats)
    {
        m_stats = stats;
    }
    
    protected void
    SetDataFinished()
    {
        if (m_stats == null || m_stats.isEmpty()) {
            m_lvList.setAdapter(null);
            m_vPieChart.SetAdapter(null);
            m_vEmptyResult.setVisibility(View.VISIBLE);
            if (aDebug.ENABLED)
                aDebug.d(LOG_TAG, "SetDataFinished(): empty result");
            return;
        }
        
        m_vEmptyResult.setVisibility(View.INVISIBLE);
        
        m_lvList.setAdapter(new MyListAdapter(getActivity()));
        m_vPieChart.SetAdapter(new MyPieChartAdapter());
        
        if (m_nLastCheckedPos >= 0)
            _SetChecked(m_nLastCheckedPos);
        else
            _SetChecked(m_nMyIdx);
        
        String strDate;
        if (m_lDataTime <= 0)
            strDate = "- none -";
        else {
            DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
            strDate = df.format(m_lDataTime);
        }
        m_tvLastUpdate.setText(strDate);
    }
    
    private void
    _SetChecked(int nPos)
    {
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "_SetChecked(): nPos=" + nPos);
        if (nPos >= 0) {
            m_lvList.setItemChecked(nPos, true);
            _OnListItemChecked(nPos, false);
        }
    }
    
    private void
    _ScrollToVisible(int nIdx)
    {
        m_lvList.setSelection(nIdx);
    }

    private void
    _OnListItemChecked(int nPos, boolean bToggle)
    {
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "_OnListItemChecked(): nPos=" + nPos + ", m_nLastCheckedPos=" + m_nLastCheckedPos);
        
        if (bToggle && m_nLastCheckedPos == nPos) {
            m_lvList.setItemChecked(m_nLastCheckedPos, false);
            nPos = -1;
        }
        else {
            _ScrollToVisible(nPos);
        }
        
        m_nLastCheckedPos = nPos;
        
        m_vPieChart.SetSelected(nPos, false);        
    }

    //PieChartView
    @Override public void 
    OnPieSelected(PieChartView vPieChart, int nPos)
    {
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "OnPieSelected(), nPos=" + nPos);
        if (nPos >= 0) {
            m_nLastCheckedPos = nPos;
            m_lvList.setItemChecked(nPos, true);
            _ScrollToVisible(nPos);
        }
        else {
            if (m_nLastCheckedPos >= 0) {
                m_lvList.setItemChecked(m_nLastCheckedPos, false);
                m_nLastCheckedPos = -1;
            }
        }
    }

    //AdapterView.OnItemClickListener
    @Override public void 
    onItemClick(AdapterView<?> vList, View vItem, int nPos, long lID)
    {
        if (aDebug.ENABLED)
            aDebug.d(LOG_TAG, "onItemClick(): nPos=" + nPos);
        _OnListItemChecked(nPos, true);
    }
    
    ////////////////////////////////////
    protected static class StatData {
        protected float m_fPercentage;
        protected long m_lCount;
    }
    
    ////////////////////////////////////
    private class MyPieChartAdapter extends Adapter {
        private
        MyPieChartAdapter()
        {   
        }
        
        @Override protected int 
        GetCount()
        {
            return m_stats == null ? 0 : m_stats.size();
        }
        
        @Override protected int 
        GetColor(int nPos)
        {
            final int N = CONSTS.PIE_COLORS.length;
            return CONSTS.PIE_COLORS[nPos % N];
        }

        @Override protected float 
        GetPercentage(int nPos)
        {
            if (m_stats == null) return 0f;
            return m_stats.get(nPos).m_fPercentage;
        }

        @Override protected int 
        GetActivePieIdx()
        {
            return m_nMyIdx;
        }
    }
    
    ////////////////////////////////////
    protected static class ListItemTagData {
        protected TextView m_tvLegend, m_tvPercentage, m_tvVersion, m_tvAPI, m_tvMyDevice;
        protected ImageView m_ivLegend;
    }
    
    protected abstract void SetListItemView(StatData stat, ListItemTagData tag);
    
    ////////////////////////////////////
    private class MyListAdapter extends BaseAdapter {
        private LayoutInflater m_lf;
        
        private
        MyListAdapter(Context ctx)
        {
            m_lf = LayoutInflater.from(ctx);
        }
        
        @Override public int 
        getCount()
        {
            return m_stats == null ? 0 : m_stats.size();
        }

        @Override public StatData 
        getItem(int nPos)
        {
            return m_stats == null ? null : m_stats.get(nPos);
        }

        @Override public long 
        getItemId(int nPos)
        {
            return nPos;
        }

        @Override public View 
        getView(int nPos, View vConvert, ViewGroup vParent)
        {
            ListItemTagData tag;
            if (vConvert == null) {
                vConvert = m_lf.inflate(R.layout.comm_stats_list_item, vParent, false);
                tag = new ListItemTagData();
                tag.m_ivLegend = (ImageView)vConvert.findViewById(R.id.legend_img);
                tag.m_tvLegend = (TextView)vConvert.findViewById(R.id.legend);
                tag.m_tvPercentage = (TextView)vConvert.findViewById(R.id.percentage);
                tag.m_tvVersion = (TextView)vConvert.findViewById(R.id.version);
                tag.m_tvAPI = (TextView)vConvert.findViewById(R.id.api);
                tag.m_tvMyDevice = (TextView)vConvert.findViewById(R.id.my_device);
                
                vConvert.setTag(tag);
            }
            else {
                tag = (ListItemTagData)vConvert.getTag();
                if (tag == null) return null;
            }
            
            StatData stat = getItem(nPos);
            
            tag.m_ivLegend.setBackgroundColor(CONSTS.PIE_COLORS[nPos % CONSTS.PIE_COLORS.length]);
            tag.m_tvLegend.setText(Integer.toString(nPos + 1));
            tag.m_tvPercentage.setText(String.format("%.1f%%", stat.m_fPercentage * 100));            
            if (m_nMyIdx == nPos) {
                tag.m_tvMyDevice.setText(m_strMy);
                tag.m_tvMyDevice.setVisibility(View.VISIBLE);
            }
            else {
                tag.m_tvMyDevice.setVisibility(View.GONE);
            }
            
            SetListItemView(stat, tag);
            return vConvert;
        }
    }
}
